package com.cindata

import com.cindata.dictionary.*
import com.cindata.base.*

import grails.transaction.Transactional
import org.apache.commons.lang.StringUtils
import org.apache.commons.lang.time.DateFormatUtils
import org.joda.time.DateTimeUtils

import java.text.SimpleDateFormat
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

@Transactional
class EvaluateService
{
    static scope = "singleton"
    private static int batchLimit = 5000
    def apiService
    def evaluationApiService
    def splitMatchApiService

    def sessionFactory
    Map<String, BigDecimal> progressMap = new HashMap<String, BigDecimal>(100);
    private ExecutorService evaluatePool = Executors.newFixedThreadPool(3)

    def batchInserts(List<Map> paramMapList, EstateImportBatch batch, Date currentDate)
    {
        setProgress(batch.id, BigDecimal.valueOf(0))

        estateInserts(paramMapList, batch, currentDate)

        setProgress(batch.id, BigDecimal.valueOf(100))
    }

    def batchInsertsVehicle(List<Map> paramMapList, VehicleImportBatch batch, Date currentDate)
    {
        setProgress(batch.id, BigDecimal.valueOf(0))
        if (batch.importFileType.code == 'Estate')
        {
            vehicleInserts(paramMapList, batch, currentDate)
        }
        else if (batch.importFileType.code == 'Repayment')
        {
            repaymentInserts(paramMapList, batch, currentDate)
        }
        setProgress(batch.id, BigDecimal.valueOf(100))
    }

    //    押品数据导入
    def estateInserts(List<Map> estateMapList, EstateImportBatch batch, Date currentDate)
    {
        println "estateInserts  matchNum:   " + batch.matchNum
        def i = 0
        def count = estateMapList.size()
        //        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd")
        def createBy = batch.createBy
        def BuildingTypeDictArr = BuildingTypeDict.all
        def EstateStatusArr = EstateStatusDict.all
        def HouseTypeArr = HouseTypeDict.all
        def RepaymentModeArr = RepaymentModeDict.all
        def ForwardLoanStepArr = ForwardLoanStepDict.all
        def LoanMethodArr = LoanMethodDict.all
        def AccountArr = Account.all
        def GuaranteeMethodArr = GuaranteeMethodDict.all
        def AccountNatureArr = AccountNatureDict.all
        def OrganizationNatureArr = OrganizationNatureDict.all
        def DepositedStateArr = DepositedStateDict.all
        def BuildingTypeArr = BuildingTypeDict.all
        def CityArr = City.all
        def DistrictArr = District.all
        def defaultBuildingType = BuildingTypeArr.find {
            it.code == "Residential"
        }

        estateMapList.each { Map param ->
            //遍历map集合
            param.batch = batch
            param.createdDate = currentDate
            param.createBy = createBy
            param.city = param.cityName ? CityArr.find { it.name == param.cityName } : null
            param.district = param.districtName ? DistrictArr.find {
                it.name == param.districtName && it.parentAreaId == param?.city.id
            } : null
            param.estateStatus = param.estateStatus ? EstateStatusArr.find { it.name == param.estateStatus } : null
            param.estateType = param.estateType ? HouseTypeArr.find { it.name == param.estateType } : null
            param.isFirstHouse = (param.isFirstHouse == '是' ? true : false)
            param.starRepaymentMode = param.starRepaymentMode ? RepaymentModeArr.find {
                it.name == param.starRepaymentMode
            } : null
            param.forwardLoanStep = param.forwardLoanStep ? ForwardLoanStepArr.find {
                it.name == param.forwardLoanStep
            } : null
            param.loanMethod = param.loanMethod ? LoanMethodArr.find { it.name == param.loanMethod } : null
            param.curRepaymentMode = param.curRepaymentMode ? RepaymentModeArr.find {
                it.name == param.curRepaymentMode
            } : null
            param.guaranteeInstitution = param.guaranteeInstitution ? AccountArr.find {
                it.name == param.guaranteeInstitution
            } : null
            param.guaranteeMethod = param.guaranteeMethod ? GuaranteeMethodArr.find {
                it.name == param.guaranteeMethod
            } : null
            param.borrAccountNature = param.borrAccountNature ? AccountNatureArr.find {
                it.name == param.borrAccountNature
            } : null
            param.borrWorkUnitNature = param.borrWorkUnitNature ? OrganizationNatureArr.find {
                it.name == param.borrWorkUnitNature
            } : null
            param.borrDepositedState = param.borrDepositedState ? DepositedStateArr.find {
                it.name == param.borrDepositedState
            } : null
            param.buildingType = param.buildingType ? BuildingTypeDictArr.find {
                it.name == param.buildingType
            } : defaultBuildingType
            def estateImport
            //实例化并将读取的单元格参数给其赋值
            try
            {
                estateImport = new EstateImport(param)
                estateImport.save()
                i++
                if (i % 1000 == 0)
                {
                    def progress = i / count * 100
                    setProgress(batch.id, BigDecimal.valueOf(progress))
                    sessionFactory.currentSession.flush()
                    sessionFactory.currentSession.clear()
                }
            }
            catch (Exception e)
            {
                println "EstateImport not saved, errors = ${estateImport?.errors}"
                log.error(e)
            }

        }
    }

    //    还款数据导入
    def repaymentInserts(List<Map> repaymentMapList, EstateImportBatch batch, Date currentDate)
    {
        def i = 0
        def count = repaymentMapList.size()
        //        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd")
        def createBy = batch.createBy
        def RepaymentTypeArr = RepaymentTypeDict.all
        def OverdueStateArr = OverdueStateDict.all
        def PrepaymentTypeArr = PrepaymentTypeDict.all
        repaymentMapList.each { Map param ->
            //遍历map集合
            param.batch = batch
            param.createdDate = currentDate
            param.createBy = createBy
            param.modifyBy = createBy
            param.repaymentType = param.repaymentType ? RepaymentTypeArr.find { it.name == param.repaymentType } : null
            param.overdueState = param.overdueState ? OverdueStateArr.find { it.name == param.overdueState } : null
            param.prepaymentType = param.prepaymentType ? PrepaymentTypeArr.find {
                it.name == param.prepaymentType
            } : null
            def repaymentImport
            //实例化并将读取的单元格参数给其赋值
            try
            {
                repaymentImport = new RepaymentImport(param)
                repaymentImport.save()
                i++
                if (i % 1000 == 0)
                {
                    def progress = i / count * 100
                    setProgress(batch.id, BigDecimal.valueOf(progress))
                    sessionFactory.currentSession.flush()
                    sessionFactory.currentSession.clear()
                }
            }
            catch (Exception e)
            {
                println "RepaymentImport not saved, errors = ${repaymentImport?.errors}"
                log.error(e)
            }

        }
    }

    //    车辆押品数据导入
    def vehicleInserts(List<Map> vehicleMapList, VehicleImportBatch batch, Date currentDate)
    {
        def i = 0
        def count = vehicleMapList.size()
        println "vehicleInserts  matchNum:   " + batch.matchNum

        def CityArr = City.all
        def DistrictArr = District.all
        def EstateStatusArr = EstateStatusDict.all
        //        def MortgageArr=Mortgage.all
        //        def MortgageStatusArr=MortgageStatusDict.all
        //        def MortgageCategoryArr=MortgageCategory.all
        def IdentityTypeArr = ContactIdentityType.all
        def CurrencyArr = CurrencyDict.all
        def CashabilityArr = Cashability.all
        def TypeArr = VehicleTypeDict.all
        def evaluateStatueArr = ExecStatusDict.all
        def createBy = batch.createBy

        vehicleMapList.each { Map param ->
            //遍历map集合
            param.batch = batch
            param.createdDate = currentDate
            param.createBy = createBy
            param.city = param.city ? CityArr.find { it.name == param.city } : null
            param.district = param.district ? DistrictArr.find {
                it.name == param.district && it.parentAreaId == param?.city.id
            } : null
            param.estateStatus = param.estateStatus ? EstateStatusArr.find { it.name == param.estateStatus } : null
            param.identityType = param.identityType ? IdentityTypeArr.find { it.name == param.identityType } : null
            param.cashability = param.cashability ? CashabilityArr.find { it.name == param.cashability } : null
            param.type = param.type ? TypeArr.find { it.name == param.type } : null
            param.currency = param.currency ? CurrencyArr.find { it.name == param.currency } : null
            param.account = param.account ? Account.findByName(param.account) : null
            param.evaluateStatue = param.evaluateStatue ? evaluateStatueArr.find {
                it.name == param.evaluateStatue
            } : null

            def vehicleImport
            //实例化并将读取的单元格参数给其赋值
            try
            {
                vehicleImport = new VehicleImport(param)
                vehicleImport.save()
                i++
                if (i % 1000 == 0)
                {
                    def progress = i / count * 100
                    setProgress(batch.id, BigDecimal.valueOf(progress))
                    sessionFactory.currentSession.flush()
                    sessionFactory.currentSession.clear()
                }
            }
            catch (Exception e)
            {
                println "VehicleImport not saved, errors = ${vehicleImport?.errors}"
                log.error(e)
            }

        }

    }

    //    应收账款数据导入
    def accountsReceivableInserts(List<Map> estateMapList, AccountsReceivableImportBatch batch, Date currentDate)
    {

    }

    //    金融质押数据导入
    def financialPledgeInserts(List<Map> estateMapList, FinancialPledgeImportBatch batch, Date currentDate)
    {
        setProgress(batch.id, BigDecimal.valueOf(0))
        def i = 0
        def count = estateMapList.size()

        estateMapList.each { Map param ->
            //遍历map集合
            param.province = param.province ? Province.findByName(param.province) : null
            param.city = param.city ? City.findByName(param.city) : null
            param.district = param.district && param.city ? District.findByNameAndParentArea(param.district, param.city) : null
            param.estateStatus = param.estateStatus ? EstateStatusDict.findByName(param.estateStatus) : null
            param.isEstate = (param.isEstate == '是' ? true : false)
            param.account = param.account ? Account.findByName(param.account) : null
            param.type = param.type ? FinancialPledgeTypeDict.findByName(param.type) : null
            param.identityType = param.identityType ? ContactIdentityType.findByName(param.identityType) : null
            param.isValidate = (param.isValidate == '已审核' ? true : false)
            param.currency = param.currency ? CurrencyDict.findByName(param.currency) : null
            param.cashability = param.cashability ? Cashability.findByName(param.cashability) : null
            param.isNativeDeposit = (param.isNativeDeposit == '是' ? true : false)
            param.isElectronicDeposit = (param.isElectronicDeposit == '是' ? true : false)
            param.isOrienteeringBond = (param.isOrienteeringBond == '是' ? true : false)
            param.bondAmount
            param.isRegisteredBond = (param.isRegisteredBond == '是' ? true : false)
            param.isNeedStopPayment = (param.isNeedStopPayment == '是' ? true : false)
            param.isCapitalProtected = (param.isCapitalProtected == '是' ? true : false)
            param.isRedemption = (param.isRedemption == '是' ? true : false)
            param.isHighQualityAccount = (param.isHighQualityAccount == '是' ? true : false)
            param.isHavePledgeClause = (param.isHavePledgeClause == '是' ? true : false)
            param.isAgreedPledgeRate = (param.isAgreedPledgeRate == '是' ? true : false)
            param.batch = batch
            param.createdDate = currentDate
            param.createBy = batch.createBy

            def estateImport
            //实例化并将读取的单元格参数给其赋值
            try
            {
                estateImport = new FinancialPledgeImport(param)
                if (estateImport.validate())
                {
                    estateImport.save()
                }
                else
                {
                    println estateImport.errors
                }
                i++
                if (i % 1000 == 0)
                {
                    def progress = i / count * 100
                    setProgress(batch.id, BigDecimal.valueOf(progress))
                    sessionFactory.currentSession.flush()
                    sessionFactory.currentSession.clear()
                }
            }
            catch (Exception e)
            {
                println "FinancialPledgeImport not saved, errors = ${estateImport?.errors}"
                log.error(e)
            }

        }
        setProgress(batch.id, BigDecimal.valueOf(100))
    }

    //    其他押品数据导入
    def othersCollateralInserts(List<Map> estateMapList, OtherCollateralImportBatch batch, Date currentDate)
    {

    }

    //    押品数据导入
    def contactInserts(List<Map> contactMapList, ContactImportBatch batch, Date currentDate)
    {
        setProgress(batch.id, BigDecimal.valueOf(0))
        def i = 0
        def count = contactMapList.size()
        def createBy = batch.createBy
        def ContactIdentityTypeArr = ContactIdentityType.all

        contactMapList.each { Map param ->
            //遍历map集合
            param.batch = batch
            param.identityType = param.identityType ? ContactIdentityTypeArr.find {
                it.name == param.identityType
            } : null
            param.createdDate = currentDate
            param.createBy = createBy

            def contactImport
            //实例化并将读取的单元格参数给其赋值
            try
            {
                contactImport = new ContactImport(param)
                contactImport.save flush: true
                println contactImport.errors
                if (validateParam(contactImport))
                {
                    contactImport.evaluateStatue = ExecStatusDict.findByName("成功")
                    contactImport.validSuccess()
                }
                else
                {
                    contactImport.evaluateStatue = ExecStatusDict.findByName("失败")
                    contactImport.validFailure()
                }
                contactImport.save flush: true
                i++
                if (i % 1000 == 0)
                {
                    def progress = i / count * 100
                    setProgress(batch.id, BigDecimal.valueOf(progress))
                    sessionFactory.currentSession.flush()
                    sessionFactory.currentSession.clear()
                }
            }
            catch (Exception e)
            {
                println "ContactImport not saved, errors = ${contactImport?.errors}"
                log.error(e)
            }

        }
        setProgress(batch.id, BigDecimal.valueOf(100))
    }

    def validateParam(ContactImport contactImport)
    {
        def contact = Contact.findByIdNumber(contactImport.idNumber)
        if (contact)
        {
            contactImport.reason = "借款人已经存在"
            return false
        }
        if (contactImport?.idNumber && contactImport?.idNumber.length() != 18)
        {
            contactImport.reason = "身份证长度校验失败"
            return false
        }
        return true
    }

    /**
     * 设置执行进度*/
    def setProgress(Long progressKey, BigDecimal progress)
    {
        ProgressUtil.setProgress(progressKey, progress)
    }

    def getProgress(Long progressKey)
    {
        return ProgressUtil.progressMap.get(progressKey)
    }

    /**
     * 批次评估*/
    def evaluateBatch(Serializable batchId, Integer em)
    {
        EstateImportBatch importBatch = EstateImportBatch.get(batchId)
        int count = EstateImport.countByBatch(importBatch)
        if (count > 0)
        {
            for (
                int i = 0;
                    i < (count + batchLimit - 1) / batchLimit;
                    i++)
            {
                def estateQuery = EstateImport.where {
                    batch.id == importBatch.getId()
                }
                def failedList = []
                def list = estateQuery.list([offset: i * batchLimit, max: batchLimit])
                list?.each { EstateImport bean ->
                    def param = [em: em,
                        batchNum: importBatch.id,
                        batchTotalCount: count,
                        batchLevel: '户',
                        city: bean.getCityName(),
                        address: bean.getAddress(),
                        floor: bean.getCurrentFloor(),
                        totalFloor: bean.getTotalFloor(),
                        square: bean.getBuildArea()]

                    def result = [:]
                    try
                    {
                        // 自动评估
                        if (param.em == 1)
                        {
                            // 地址拆分匹配
                            def addressSplitList = splitMatchApiService.splitMatch(bean?.city?.name, bean?.address)
                            def communityId = addressSplitList?.match_community_id
                            if (communityId && communityId != "-1")
                            {
                                bean.communityId = addressSplitList?.match_community_id?.toInteger()
                                bean.communityName = addressSplitList?.match_community_name
                                bean.buildingId = addressSplitList?.match_building_id?.toInteger()
                                bean.buildingName = addressSplitList?.match_building_name
                                bean.unitId = addressSplitList?.match_unit_id?.toInteger()
                                bean.unitName = addressSplitList?.match_unit_name
                                bean.houseId = addressSplitList?.match_house_id?.toInteger()
                                bean.houseName = addressSplitList?.match_house_name
                                bean.streetId = addressSplitList?.match_street_id?.toInteger()
                                bean.streetName = addressSplitList?.match_street_name
                                param['name'] = addressSplitList?.match_community_name

                                // 评估
                                result = apiService.evaluate(param)
                            }
                            else
                            {
                                result['code'] = "-1"
                                result['message'] = "地址拆分失败"
                            }
                        }

                        // 人工评估
                        if (param.em == 7)
                        {
                            result = apiService.evaluate(param)
                        }

                        // 自动评估和人工
                        if (param.em == 8)
                        {
                            // 地址拆分匹配
                            def addressSplitList = splitMatchApiService.splitMatch(bean?.city?.name, bean?.address)
                            def communityId = addressSplitList?.match_community_id
                            if (communityId && communityId != "-1")
                            {
                                bean.communityId = addressSplitList?.match_community_id?.toInteger()
                                bean.communityName = addressSplitList?.match_community_name
                                bean.buildingId = addressSplitList?.match_building_id?.toInteger()
                                bean.buildingName = addressSplitList?.match_building_name
                                bean.unitId = addressSplitList?.match_unit_id?.toInteger()
                                bean.unitName = addressSplitList?.match_unit_name
                                bean.houseId = addressSplitList?.match_house_id?.toInteger()
                                bean.houseName = addressSplitList?.match_house_name
                                bean.streetId = addressSplitList?.match_street_id?.toInteger()
                                bean.streetName = addressSplitList?.match_street_name

                                // 评估
                                param['em'] = 1
                                param['name'] = addressSplitList?.match_community_name
                                result = apiService.evaluate(param)
                                if (result && result?.code != "0")
                                {
                                    failedList.add(bean)
                                    param['em'] = 9
                                }
                            }
                            else
                            {
                                result['code'] = "-1"
                                result['message'] = "地址拆分失败"
                            }
                        }

                        // 发起远程评估以后，要产进行计费
                        UserCost.CreateByEstateEvaluate(importBatch.id, bean)
                        if (result)
                        {
                            if (param.em == 1)
                            {
                                println "自动评估"
                                this.automaticEvaluateCallBack(bean, result)
                            }
                            else if (param.em == 7)
                            {
                                println "人工评估"
                                this.artificialEvaluateCallBack(bean, result)
                            }
                            else if (param.em == 8)
                            {
                                println "自动加人工评估"
                                this.evaluateCallBack(bean, result)
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        bean.setEvaluateStatue(ExecStatusDict.FAILURE())
                        bean.setEvaluateCode("9999")
                        bean.setFailReason("远程API调用失败:${ex.getMessage()}")
                        bean.save(flush: true)
                        bean.evaluteFailure()
                        log.error("9999远程API调用失败")
                    }
                }

                // 批量处理自动加人工方式失败记录
                if (failedList?.size() > 0)
                {
                    failedBeanBatchEvaluate(failedList)
                }
            }
        }
    }

    // 自动加人工评估：失败押品转人工评估
    def failedBeanBatchEvaluate(List<Map> failedList)
    {
        int count = failedList?.size()
        failedList?.each { EstateImport bean ->
            def param = [em: 7,
                batchNum: bean?.batch.id,
                batchTotalCount: count,
                batchLevel: '户',
                city: bean.getCityName(),
                address: bean.getAddress(),
                floor: bean.getCurrentFloor(),
                totalFloor: bean.getTotalFloor(),
                square: bean.getBuildArea()]

            def result = [:]
            try
            {
                // 人工评估
                result = apiService.evaluate(param)
                if (result)
                {
                    println "自动加人工方式失败批量转人工"
                    this.artificialEvaluateCallBack(bean, result)
                }
            }
            catch (Exception ex)
            {
                bean.setEvaluateStatue(ExecStatusDict.FAILURE())
                bean.setEvaluateCode("9999")
                bean.setFailReason("远程API调用失败:${ex.getMessage()}")
                bean.save(flush: true)
                bean.evaluteFailure()
                log.error("9999远程API调用失败")
            }
        }
    }

    // 自动评估：失败押品转人工评估
    def evaluateFailureEstate(Serializable batchId)
    {
        EstateImportBatch importBatch = EstateImportBatch.get(batchId)
        int count = EstateImport.countByBatchAndEvaluateStatue(importBatch, ExecStatusDict.FAILURE())
        if (count > 0)
        {
            for (
                int i = 0;
                    i < (count + batchLimit - 1) / batchLimit;
                    i++)
            {
                def estateQuery = EstateImport.where {
                    batch.id == importBatch.getId() && evaluateStatue.name == "失败"
                }
                def list = estateQuery.list([offset: i * batchLimit, max: batchLimit])
                list?.each { EstateImport bean ->
                    def param = [em: 7,
                        batchNum: importBatch.id,
                        batchTotalCount: count,
                        batchLevel: '户',
                        city: bean.getCityName(),
                        address: bean.getAddress(),
                        floor: bean.getCurrentFloor(),
                        totalFloor: bean.getTotalFloor(),
                        square: bean.getBuildArea()]

                    def result = [:]
                    try
                    {
                        result = apiService.evaluate(param)
                        if (result)
                        {
                            println "人工评估"
                            this.artificialEvaluateCallBack(bean, result)
                        }
                    }
                    catch (Exception ex)
                    {
                        bean.setEvaluateStatue(ExecStatusDict.FAILURE())
                        bean.setEvaluateCode("9999")
                        bean.setFailReason("远程API调用失败:${ex.getMessage()}")
                        bean.save(flush: true)
                        bean.evaluteFailure()
                        log.error("9999远程API调用失败")
                    }
                }
            }
        }
    }

    // 自动评估
    def automaticEvaluateCallBack(EstateImport bean, Map result)
    {
        println "============= # automaticEvaluateCallBack 自动评估 ===================="
        println "result:" + result
        if (result && bean)
        {
            log.info(result)
            // 发起远程评估收到反馈结果以后，要产进行计费
            if ("0".equals(result.code))
            {
                // 自动评估成功
                bean.setModifiedDate(new Date())
                bean.setUnitPrice(result.unitprice)
                bean.setTotalPrice(result.saleprice)
                bean.setEvaluateCode(result.evaluateCode)
                bean.setEvaluateDate(Date.parse("yyyy-MM-dd H:m:s", result.evaluateDate))
                bean.setLatestEvaluateDate(Date.parse("yyyy-MM-dd H:m:s", result.evaluateDate))
                // bean.setCommunityId(result.info.communityId)
                // bean.setCommunityName(result.info.name)
                bean.setBuildYear(result.info.buildYear)
                bean.setEvaluateStatue(ExecStatusDict.SUCCESS())
                bean.setEvaluateType(EvaluateDict.AUTOMATIC())
                bean.save(flush: true)

                // 2成功计费
                bean.evaluteSuccess()
                return 0
            }
            else
            {
                //评估失败
                bean.setEvaluateStatue(ExecStatusDict.FAILURE())
                bean.setEvaluateType(EvaluateDict.AUTOMATIC())
                bean.setEvaluateCode(result.evaluateCode)
                bean.setFailReason(result.message)
                bean.save(flush: true)
                bean.evaluteFailure()
                log.error(result.code + "" + result.message)
                return result.code
            }
        }
    }

    // 人工评估
    def artificialEvaluateCallBack(EstateImport bean, Map result)
    {
        println "============= # artificialEvaluateCallBack 人工评估 ===================="
        println "result:" + result
        if (result && bean)
        {
            log.info(result)
            if ("4".equals(result.code))
            {
                // 转人工评估
                bean.setEvaluateCode(result.evaluateCode)
                bean.setEvaluateType(EvaluateDict.ARTIFICIAL())
                bean.setEvaluateStatue(ExecStatusDict.EXECUTING())
                bean.save(flush: true)
                return 0
            }
            else
            {
                //评估失败
                bean.setEvaluateStatue(ExecStatusDict.FAILURE())
                bean.setEvaluateCode(result.evaluateCode)
                bean.setFailReason(result.message)
                bean.save(flush: true)
                bean.evaluteFailure()
                log.error(result.code + "" + result.message)
                return result.code
            }
        }
    }

    // 自动加人工评估 
    def evaluateCallBack(EstateImport bean, Map result)
    {
        println "============= # evaluateCallBack 自动加人工 ===================="
        println "result:" + result
        if (result && bean)
        {
            log.info(result)
            // 发起远程评估收到反馈结果以后，要产进行计费
            if ("0".equals(result.code))
            {
                // 自动评估成功
                bean.setModifiedDate(new Date())
                bean.setUnitPrice(result.unitprice)
                bean.setTotalPrice(result.saleprice)
                bean.setEvaluateCode(result.evaluateCode)
                // bean.setCommunityId(result.info.communityId)
                // bean.setCommunityName(result.info.name)
                bean.setBuildYear(result.info.buildYear)
                bean.setEvaluateDate(Date.parse("yyyy-MM-dd H:m:s", result.evaluateDate))
                bean.setLatestEvaluateDate(Date.parse("yyyy-MM-dd H:m:s", result.evaluateDate))
                bean.setEvaluateStatue(ExecStatusDict.SUCCESS())
                bean.setEvaluateType(EvaluateDict.AUTOMATIC())
                bean.save(flush: true)

                // 2成功计费
                bean.evaluteSuccess()
                return 0
            }
            else if ("4".equals(result.code))
            {
                // 转人工评估
                bean.setEvaluateCode(result.evaluateCode)
                bean.setEvaluateType(EvaluateDict.ARTIFICIAL())
                bean.setEvaluateStatue(ExecStatusDict.EXECUTING())
                bean.save(flush: true)
                return 0
            }
            else
            {
                //评估失败
                bean.setEvaluateStatue(ExecStatusDict.FAILURE())
                bean.setEvaluateCode(result.evaluateCode)
                bean.setFailReason(result.message)
                bean.save(flush: true)
                bean.evaluteFailure()
                log.error(result.code + "" + result.message)
                return result.code
            }
        }
    }

    /**
     * 押品表押品批次复估*/
    def estateBatchReEvaluation(Serializable batchId, Integer em)
    {
        EstateImportBatch importBatch = EstateImportBatch.get(batchId)
        int count = BatchEstate.countByBatch(importBatch)

        if (count > 0)
        {
            for (
                int i = 0;
                    i < (count + batchLimit - 1) / batchLimit;
                    i++)
            {
                def estateQuery = BatchEstate.where {
                    batch.id == importBatch.getId()
                }
                def failedList = []
                def list = estateQuery.list([offset: i * batchLimit, max: batchLimit])
                list?.each { BatchEstate bean ->
                    def param = [em: em,
                        batchNum: importBatch.id,
                        batchTotalCount: count,
                        batchLevel: '户',
                        city: bean?.estate?.city?.name,
                        address: bean?.estate?.sourceAddress,
                        floor: bean?.estate?.sourceTotalFloor,
                        totalFloor: bean.estate?.sourceTotalFloor,
                        square: bean?.estate?.sourceBuildArea,
                        name: bean?.estate?.communityName]

                    def result = [:]
                    try
                    {
                        // 自动评估
                        if (param.em == 1)
                        {
                            println param

                            // 地址拆分匹配
                            def addressSplitList = splitMatchApiService.splitMatch(param.city, param.address)
                            def communityId = addressSplitList?.match_community_id
                            if (communityId && communityId != "-1")
                            {
                                // bean.communityId = addressSplitList?.match_community_id?.toInteger()
                                // bean.communityName = addressSplitList?.match_community_name
                                // bean.buildingId = addressSplitList?.match_building_id?.toInteger()
                                // bean.buildingName = addressSplitList?.match_building_name
                                // bean.unitId = addressSplitList?.match_unit_id?.toInteger()
                                // bean.unitName = addressSplitList?.match_unit_name
                                // bean.houseId = addressSplitList?.match_house_id?.toInteger()
                                // bean.houseName = addressSplitList?.match_house_name
                                // bean.streetId = addressSplitList?.match_street_id?.toInteger()
                                // bean.streetName = addressSplitList?.match_street_name
                                param['name'] = param['name'] ?: addressSplitList?.match_community_name

                                // 评估
                                result = apiService.evaluate(param)

                                println result

                            }
                            else
                            {
                                result['code'] = "-1"
                                result['evaluateCode'] = "-1"
                                result['message'] = "地址拆分失败"
                            }
                        }

                        // 人工评估
                        if (param.em == 7)
                        {
                            println param
                            result = apiService.evaluate(param)
                        }

                        // 自动评估和人工
                        if (param.em == 8)
                        {
                            // 地址拆分匹配
                            def addressSplitList = splitMatchApiService.splitMatch(param.city, param.address)
                            def communityId = addressSplitList?.match_community_id
                            if (communityId && communityId != "-1")
                            {
                                // bean.communityId = addressSplitList?.match_community_id?.toInteger()
                                // bean.communityName = addressSplitList?.match_community_name
                                // bean.buildingId = addressSplitList?.match_building_id?.toInteger()
                                // bean.buildingName = addressSplitList?.match_building_name
                                // bean.unitId = addressSplitList?.match_unit_id?.toInteger()
                                // bean.unitName = addressSplitList?.match_unit_name
                                // bean.houseId = addressSplitList?.match_house_id?.toInteger()
                                // bean.houseName = addressSplitList?.match_house_name
                                // bean.streetId = addressSplitList?.match_street_id?.toInteger()
                                // bean.streetName = addressSplitList?.match_street_name

                                // 评估
                                param['em'] = 1
                                param['name'] = addressSplitList?.match_community_name
                                result = apiService.evaluate(param)
                                if (result && result?.code != "0")
                                {
                                    failedList.add(bean)
                                    param['em'] = 9
                                }
                            }
                            else
                            {
                                result['code'] = "-1"
                                result['message'] = "地址拆分失败"
                            }
                        }

                        // 发起远程评估以后，要产进行计费
                        // UserCost.CreateByEstateEvaluate(importBatch.id, bean)
                        if (result)
                        {
                            if (param.em == 1)
                            {
                                println "自动评估"
                                this.reAutomaticEvaluateCallBack(bean, result)
                            }
                            else if (param.em == 7)
                            {
                                println "人工评估"
                                this.reArtificialEvaluateCallBack(bean, result)
                            }
                            else if (param.em == 8)
                            {
                                println "自动加人工评估"
                                this.evaluateCallBack(bean, result)
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        bean.setEvaluateStatue(ExecStatusDict.FAILURE())
                        bean.setEvaluateCode("9999")
                        bean.setFailReason("远程API调用失败:${ex.getMessage()}")
                        bean.save(flush: true)
                        log.error("9999远程API调用失败")
                    }
                }

                // 批量处理自动加人工方式失败记录
                if (failedList?.size() > 0)
                {
                    reFailedBeanBatchEvaluate(failedList)
                }
            }
        }
    }

    // 自动评估
    def reAutomaticEvaluateCallBack(BatchEstate bean, Map result)
    {
        println "============= # reAutomaticEvaluateCallBack 自动评估 ===================="
        println "result:" + result
        if (result && bean)
        {
            def estate = bean?.estate
            if ("0".equals(result.code))
            {
                estate.setModifiedDate(new Date())
                estate.setUnitPrice(result.unitprice)
                estate.setTotalPrice(result.saleprice)
                estate.setLatestEvaluatePrice(result.saleprice)
                estate.setLatestEvaluateDate(Date.parse("yyyy-MM-dd H:m:s", result.evaluateDate))
                estate.save(flush: true)

                bean.setEvaluateStatue(ExecStatusDict.SUCCESS())
                bean.setModifiedDate(new Date())
                bean.setEvaluateCode(result.evaluateCode)
                bean.save(flush: true)

                ValuationHistory valuationHistory = new ValuationHistory()
                valuationHistory.evaluateCode = result.evaluateCode
                valuationHistory.name = estate?.name
                valuationHistory.valuationDate = estate?.latestEvaluateDate
                valuationHistory.unitPrice = estate?.unitPrice
                valuationHistory.totalPrice = estate?.totalPrice
                valuationHistory.sourceId = estate?.id
                valuationHistory.sourceClass = "estate"
                valuationHistory.evaluateStatus = ExecStatusDict.SUCCESS()
                valuationHistory.evaluateType = EvaluateDict.AUTOMATIC()
                valuationHistory.save(flush: true)

                return 0
            }
            else
            {
                //评估失败
                bean.setEvaluateStatue(ExecStatusDict.FAILURE())
                bean.setEvaluateCode(result.evaluateCode)
                bean.setModifiedDate(new Date())
                bean.setFailReason(result.message)
                bean.save(flush: true)

                ValuationHistory valuationHistory = new ValuationHistory()
                valuationHistory.evaluateCode = result.evaluateCode
                valuationHistory.failReason = result.message
                valuationHistory.name = estate?.name
                valuationHistory.valuationDate = new Date()
                valuationHistory.sourceId = estate?.id
                valuationHistory.sourceClass = "estate"
                valuationHistory.evaluateStatus = ExecStatusDict.FAILURE()
                valuationHistory.evaluateType = EvaluateDict.AUTOMATIC()
                valuationHistory.save(flush: true)

                return result.code
            }
        }
    }

    // 人工评估
    def reArtificialEvaluateCallBack(BatchEstate bean, Map result)
    {
        println "============= # reArtificialEvaluateCallBack 人工评估 ===================="
        println "result:" + result
        if (result && bean)
        {
            def estate = bean?.estate
            if ("4".equals(result.code))
            {
                // 转人工评估
                bean.setModifiedDate(new Date())
                bean.setEvaluateCode(result.evaluateCode)
                bean.setEvaluateStatue(ExecStatusDict.EXECUTING())
                bean.save(flush: true)

                ValuationHistory valuationHistory = new ValuationHistory()
                valuationHistory.evaluateCode = bean?.evaluateCode
                valuationHistory.name = estate?.name
                valuationHistory.sourceId = estate?.id
                valuationHistory.sourceClass = "estate"
                valuationHistory.evaluateStatus = ExecStatusDict.EXECUTING()
                valuationHistory.evaluateType = EvaluateDict.ARTIFICIAL()
                valuationHistory.save(flush: true)

                return 0
            }
            else
            {
                //评估失败
                bean.setModifiedDate(new Date())
                bean.setEvaluateCode(result.evaluateCode)
                bean.setEvaluateStatue(ExecStatusDict.FAILURE())
                bean.setFailReason(result.message)
                bean.save(flush: true)
                log.error(result.code + "" + result.message)

                ValuationHistory valuationHistory = new ValuationHistory()
                valuationHistory.evaluateCode = result?.evaluateCode
                valuationHistory.failReason = result?.message
                valuationHistory.name = estate?.name
                valuationHistory.sourceId = estate?.id
                valuationHistory.sourceClass = "estate"
                valuationHistory.evaluateStatus = ExecStatusDict.FAILURE()
                valuationHistory.evaluateType = EvaluateDict.ARTIFICIAL()
                valuationHistory.save(flush: true)

                return result.code
            }
        }
    }

    // 自动加人工评估：失败押品转人工评估
    def reFailedBeanBatchEvaluate(List<Map> failedList)
    {
        int count = failedList?.size()
        failedList?.each { BatchEstate bean ->
            def param = [em: 7,
                batchNum: bean?.batch.id,
                batchTotalCount: count,
                batchLevel: '户',
                city: bean?.estate?.city?.name,
                address: bean?.estate?.sourceAddress,
                floor: bean?.estate?.sourceTotalFloor,
                totalFloor: bean.estate?.sourceTotalFloor,
                square: bean?.estate?.sourceBuildArea,
                name: bean?.estate?.communityName]

            def result = [:]
            try
            {
                // 人工评估
                result = apiService.evaluate(param)
                if (result)
                {
                    println "自动加人工方式失败批量转人工"
                    this.reArtificialEvaluateCallBack(bean, result)
                }
            }
            catch (Exception ex)
            {
                bean.setEvaluateStatue(ExecStatusDict.FAILURE())
                bean.setEvaluateCode("9999")
                bean.setFailReason("远程API调用失败:${ex.getMessage()}")
                bean.save(flush: true)
                log.error("9999远程API调用失败")
            }
        }
    }
}
